/**** \file chainedlib/chainedlist.h
 * \brief Otter double Chained List declaration
 * \author JD <brossill@enseirb.fr>
 * \date 27.04.2007
 */

#ifndef CHAINEDLIST_H
#define CHAINEDLIST_H

#define CHLIST "CHAINED LIST: "

/** \brief Chained list node
*/
typedef struct _CLNode_s
{
  struct _CLNode_s* prev;
  struct _CLNode_s* next;

  void* data;
  
} CLNode_s;

/** \brief Create a new chained list
  * \return Reference to the root node
*/
CLNode_s* CL_create();

/** \brief Destroy the chained list
  * \param root Reference to the root node
  * of the list
  * \warning This function doesn't free 
  * data blocks.
  * To do so use: CL_map(root, free);
  */
void CL_destroy(CLNode_s* root);

/** \brief Return first element
  */
CLNode_s* CL_first(CLNode_s* root);

/** \brief Run a function on every data node 
  * in the list.
  * \param root Reference to the root node of
  * the list.
  * \param func Reference to the function 
  * to run.
  * Prototype must be : void (*)(void*)
*/
void CL_map(CLNode_s* root, void(*func)(void*));

/** \brief Add a new node at the beginning of
  * the list.
  * \param root Reference to the root node
  * of the list.
  * \param data Reference which will be contained
  * by the node.
  * \return Reference to the new node.
*/
CLNode_s* CL_push(CLNode_s* root, void* data);

/** \brief Add a new node at the end of the list.
  * \param root Reference to the root node of the list
  * \param data Reference which will be contained by
  *the node.
  * \return Reference to the new node
  * \warning This function go through the whole list to
  *reach the end. ( O(n) complexity) 
  */
CLNode_s* CL_push_back(CLNode_s* root, void* data);

/** \brief Remove a node  from the list
  * \param node Node to remove
  */
void CL_remove(CLNode_s* node);


/** \brief Search a node which have node->data equal
  * to data.
  * \param root Reference to the root node
  * \param data Reference to the searched data
  * \return Reference to the matching node
  */
CLNode_s* CL_search_data(CLNode_s* root, void* data);

/** \brief Search a node which returns true (>0) with
  * the user function.
  * \param root Reference to the root node
  * \param test Reference to the test function :
  * char test( void* data, void* value )
  * \param value Reference to the data value which will
  * be given to test.
  * \return Reference to the matching node.
*/
CLNode_s* CL_search_user(CLNode_s* root,
                        char(*test)(void*,void*),
                        void* value );
                        

#endif/*CHAINEDLIST_H*/
